//手写vue实例
//导入数据响应式
import reactive from "./reactive";
import pools from './pools';
import event from './event';
import {
  render
} from './render';


function createApp(component) {
  // console.log(component);
  //这里component是自己写的vue-loader编译解析后的组件对象
  /**
   * {
   *   template: '  <div>    <div>      <img v-if="isShowImg1" class…n @click="showImg2">Show Image 2</button>  </div>', 
   *   name: 'App', 
   *   methods: {…}, 
   *   data: ƒ
   * }
   */

  const vm = {};

  const $data = component.data();
  const $template = component.template;
  const $methods = component.methods;

  //挂载属性到vm实例
  vm.mount = mount;

  vm.$template = $template;
  vm.$methods = $methods;

  vm.DOM = createDOM($template);

  //定义两个Map数据类型的池子
  //- 池子1：保存的节点和类型(`v-if`/`v-show`)和绑定事件方法名称
  //池子2：保存节点和事件类型(`click`/`change`/`...`)和绑定事件的处理函数方法(`handler`)
  const {
    propsPool,
    eventsPool
  } = pools(vm.DOM, vm.$methods);

  /**
   * console.log(propsPool);
   * Map(2) {
   *   img.img => {type: 'v-if', prop: 'isShowImg1'}, 
   *   img.img => {type: 'v-show', prop: 'isShowImg2'
   * }
   */

  /**
   * console.log(eventsPool);
   * Map(2) {
   *   button => {type: 'click', prop: 'showImg1'}, 
   *   button => {type: 'click', prop: 'showImg2'
   * }
   */

  const init = () => {
    //数据响应式
    reactive(vm, $data, propsPool);

    //事件绑定
    event(vm, eventsPool);

    //渲染
    render(vm, propsPool);
  }

  init();

  return vm;
}

//将template对象里的字符串转为DOM节点
function createDOM(template) {
  const _c = document.createElement('div');

  _c.innerHTML = template;

  //去掉多出的外层div标签
  const firstChildNode = getFirstElementChild(_c);
  /**
   * console.log(firstChildNode);
   * <div>
   *   <div>...</div>
   *   <button @click="showImg1">Show Image 1</button>
   *   <button @click="showImg2">Show Image 2</button>
   * </div>
   */

  return firstChildNode;

}

//去掉多出的外层div标签
function getFirstElementChild(node) {
  const childNodes = node.childNodes;

  let childNode;

  for (let i = 0; i < childNodes.length; i++) {
    childNode = childNodes[i];

    //元素节点时
    if (childNode.nodeType === 1) {
      return childNode;
    }
  }
}

//挂载DOM
function mount(el) {
  // console.log(el);
  //#app

  document.querySelector(el).appendChild(this.DOM);

}

export {
  createApp
}